# -*- coding: utf-8 -*-

"""
This script is for communication with Maya.
Maya have to has opened socket with following mel script.

commandPort -n ":2222" -eo;

Since this script is running as thread, be careful about synchronizing with main thread.
Even print function can be a threat to stability.
"""

import socket
import thread
import select
import wx
import wx.lib.newevent

# ---------- My Modules ---------- #
import saveTempFile

# ---------- Events ---------- #
(EventConnectionOutput, EVT_CONNECTION_OUTPUT) = wx.lib.newevent.NewEvent()
(EventConnectionStatus, EVT_CONNECTION_STATUS) = wx.lib.newevent.NewEvent()
(EventConnectionClose, EVT_CONNECTION_CLOSE) = wx.lib.newevent.NewEvent()


class ConnectToMaya():
	def __init__(self, parent, host, port):
		self.parent = parent
		self.host = host
		self.port = port
	
	def start(self):
		self.keep_running=1
		thread.start_new_thread(self.run,())
	
	def stop(self):
		""" hohehohe2 version of closing socket function """
		
		keep_running=0
		if self.sSock==None:
			msg = 'There is no connection already.'
			self._eventStatus(msg)
			return None
		self.sSock.shutdown(socket.SHUT_RDWR)
		self.sSock == None
	
	def sendScript(self, ext, text):
		if ext=='py':
			tmpFile = saveTempFile.saveData( text, code='py' )
			cmd = "python( \"execfile('"+tmpFile.replace('\\', '/')+"')\")"
		elif ext == 'mel':
			tmpFile = saveTempFile.saveData( text, code='mel' )
			cmd = "source \"%s\";" % tmpFile.replace('\\', '/')
		else:
			return None
		
		cmd = ('$fileId=`fopen "' + tmpFile.replace('\\', '/') + '" "r"`;'
			   + 'string $nextLine = `fgetline $fileId`;'
			   + 'while ( size( $nextLine ) > 0 ) {'
			   + '	print ( $nextLine );'
			   + '	$nextLine = `fgetline $fileId`;'
			   + '}'
			   + 'fclose $fileId;'
			   + 'print ( "\\n" );' + cmd )
		self.send(cmd)
		
	def send(self, cmd):
		if self.sSock==None:
			msg = 'There is no connection. Try File > Connect to Maya'
			self._eventStatus(msg)
			return None
		try:
			self.sSock.send(cmd)
		except socket.error, e:
			#Never get this
			msg = 'Broken Socket.'
			self._eventStatus(msg)
			self.sSock.close()
			self._eventClose()
			self.sSock=None
			
	def run(self):
		try:
			self.sSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
			self.sSock.connect((self.host, self.port))
			self.sSock.send('print "// ----- Connection From Mayapad ----- //\\n";')
			if self.sSock.recv(1024):
				self._eventStatus('Connection made.')
		except socket.error, e:
			msg = ('Can not connect to Maya!'
					+ 'Please run following command in Maya:'
					+ 'commandPort -n ":2222" -eo;')
			self._eventStatus(msg)
			self.sSock.close()
			self._eventClose()
			self.sSock=None
			return None
			
		while self.keep_running:
			#print 'start listening'
			try:
				data = self.sSock.recv(1024)
			except socket.error, e:
				msg = 'Connection reset by peer. Maya might be crushed.'
				self._eventStatus(msg)
				self.keep_running = None
				break
			
			if not data:
				msg = "Maya finished. "
				self._eventStatus(msg)
				self.keep_running = None
			elif data=='':
				msg = "Connection closed! "
				self._eventStatus(msg)
				self.keep_running = None
			else:
				self._eventOutput(data)
		self.sSock.close()
		self.sSock=None
		msg = 'Socket completely closed'
		self._eventStatus(msg, append=True)
		self._eventClose()
		
		return None
	
	def _eventOutput(self, msg):
		evt = EventConnectionOutput(output=msg)
		wx.PostEvent(self.parent, evt)
	
	def _eventStatus(self, msg, append=False):
		evt = EventConnectionStatus(status=msg, append=append)
		wx.PostEvent(self.parent, evt)

	def _eventClose(self):
		evt = EventConnectionClose()
		wx.PostEvent(self.parent, evt)

